package io.plus.user_interface.redis;

import io.plus.user_interface.redis.JedisTemplate.ExpirePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 定时更新redis的过期时间
 */
public class ExpireTask {
    private static Logger log = LoggerFactory.getLogger(ExpireTask.class);

    private static boolean started = false;

    private static LinkedBlockingQueue<ExpireVo> expireVoQueue = new LinkedBlockingQueue<ExpireVo>();

    private ExpireTask() {

    }

    public static void add(String cacheName, String key, Serializable value, long expire) {
        ExpireVo expireVo = new ExpireVo(cacheName, key, value, expire);
        expireVoQueue.offer(expireVo);
    }

    public static void start() {
        if (started) {
            return;
        }
        synchronized (ExpireTask.class) {
            if (started) {
                return;
            }
            started = true;
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                List<ExpirePair<String, Void, Integer>> expirePairList = new ArrayList<ExpirePair<String, Void, Integer>>();
                int count = 0;
                while (true) {
                    try {
                        ExpireVo expireVo = expireVoQueue.poll();
                        if (expireVo != null) {
                            expirePairList.add(JedisTemplate.me().makePairEx(expireVo.getKey(), null, Integer.parseInt(expireVo.getExpire() + "")));
                            count++;
                        }
                        if (count > 0 && expireVo == null) {
                            log.debug("批量更新缓存过期时间,更新数量:" + expirePairList.size());
                            JedisTemplate.me().batchSetExpire(expirePairList);
                            expirePairList.clear();
                            count = 0;
                        } else if (count == 0 && expireVo == null) {
                            try {
                                Thread.sleep(1000 * 5);
                            } catch (InterruptedException e) {
                                log.error(e.toString(), e);
                            }
                        }
                    } catch (Throwable e) {
                        log.error(e.getMessage(), e);
                    }
                }
            }
        }, ExpireTask.class.getName()).start();
    }
}
